//
// Created by 23602 on 2024-07-07.
//

#ifndef ASYNCTASK_ASYNCTASK_HPP
#define ASYNCTASK_ASYNCTASK_HPP
#include <vector>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <memory>
#include <functional>
#include <atomic>

using Byte = uint8_t;
using Buffer = std::vector<uint8_t>;
using BufferPtr = std::unique_ptr<Buffer>;
using BufferPtrVec = std::vector<BufferPtr>;
class AsyncTask {
    // 超时时间
    uint8_t timeout_ = 3;
    // 最大缓冲区大小, 目前用于保存h265帧数据，512Kb
    const size_t maxBufferSize = 1024 * 512;
    // 当缓冲区满了，或者怎么样，就调用这个函数. 例如写文件，或者交给ffmpeg处理
    std::function<void(const Buffer&)> onBufferFull_;
    std::atomic<bool> isRunning_ = true;
    std::condition_variable cv_;
    std::mutex mtx_;
    std::thread taskThread_;
    BufferPtr curbuffer_ = nullptr;   // 当前缓冲区
    BufferPtr nextBuffer_ = nullptr;  // 预备的缓冲区
    BufferPtrVec buffer_;
    // 使用四缓冲，内存不值钱

public:
    AsyncTask(std::function<void(const Buffer&)> onBufferFull, uint32_t maxBuffSize, uint8_t timeout = 3);
    AsyncTask(const AsyncTask&) = delete;
    AsyncTask& operator=(const AsyncTask&) = delete;
    
    void append(const Buffer& buff);
    void append(const Byte* buff, uint32_t size);
    void stop() {
        isRunning_ = false;
        cv_.notify_one();
        if (taskThread_.joinable()) {
            taskThread_.join();
        }
    }
//    void setOnBufferFull(std::function<void(const Buffer&)> onBufferFull);
private:
    void threadFunc();
    void reset();
    bool isFull(const Buffer* buff, int size) {
        if (!buff) {
            return false;
        }
        return buff->size() + size >= maxBufferSize;
    }
    // 考虑是否放置完整的一帧数据
    bool isFull(const Buffer* buff_, const Buffer* buffer) {
        return buffer->size() + buff_->size() >= maxBufferSize;
    }
    
};
/*


 *
 *
 *
 *
 * */

#endif //ASYNCTASK_ASYNCTASK_HPP
